import logging
import concurrent_log_handler

from django.db import connections

from pyftpdlib.servers import (
    # FTPServer,
    # ThreadedFTPServer,
    MultiprocessFTPServer
)
from pyftpdlib.log import logger


from harbor_file_system import HarborFileSystem, GlobalConfig, global_configs
from harbor_auth import HarborAuthorizer
from harbor_handler import HarborDTPHandler, HarborFTPHandler, work_mode_in_tls


class StopError(BaseException):
    pass


class MyMultiprocessFTPServer(MultiprocessFTPServer):
    """"""

    def _start_task(self, *args, **kwargs):
        for conn in connections.all():
            conn.close()

        return super(MyMultiprocessFTPServer, self)._start_task(*args, **kwargs)


def main():
    # Instantiate a dummy authorizer for managing 'virtual' users
    authorizer = HarborAuthorizer()

    # Instantiate FTP handler class
    handler = HarborFTPHandler

    handler.abstracted_fs = HarborFileSystem
    handler.dtp_handler = HarborDTPHandler
    handler.authorizer = authorizer
    # global_config = GlobalConfig().get_global_config()
    global_config = global_configs.get_configs()
    if work_mode_in_tls:
        print('work mode in TLS')
        ftp_cert_file_path = global_config[GlobalConfig.ConfigName.FTP_CERT_FILE_PATH.value] if GlobalConfig.ConfigName.FTP_CERT_FILE_PATH.value in global_config else '/etc/nginx/conf.d/ftp-keycert.pem'
        handler.certfile = ftp_cert_file_path
        handler.tls_data_required = True

    logging.basicConfig(level=logging.INFO)


    ftp_log_path = global_config[GlobalConfig.ConfigName.FTP_LOG_PATH.value] if GlobalConfig.ConfigName.FTP_LOG_PATH.value in global_config else '/var/log/nginx/ftp.log'
    file_handler = concurrent_log_handler.ConcurrentRotatingFileHandler(filename=ftp_log_path,
                                                                        maxBytes=1024 ** 2 * 128,
                                                                        backupCount=10, use_gzip=True)

    file_handler.setLevel(logging.INFO)
    logger.addHandler(file_handler)

    # Define a customized banner (string returned when client connects)
    handler.banner = "pyftpdlib based ftpd ready."

    # Specify a masquerade address and the range of ports to use for
    # passive connections.  Decomment in case you're behind a NAT.
    # handler.masquerade_address = '151.25.42.11'
    handler.passive_ports = range(2000, 3000)

    # server = FTPServer(address, handler)
    # server = ThreadedFTPServer(address, handler)
    while True:
        try:
            init_server_and_run(handler)
        except (KeyboardInterrupt, SystemExit):
            break
        except StopError as e:
            raise e
        except Exception as e:
            continue
        else:  # 正常退出
            break


def init_server_and_run(handler):
    address = ('0.0.0.0', 21)
    try:
        server = MyMultiprocessFTPServer(address, handler)
    except Exception as exc:
        raise StopError(str(exc))

    # set a limit for connections
    server.max_cons = 2048
    server.max_cons_per_ip = 2048

    # start ftp server
    server.serve_forever()
    server.close_all()


if __name__ == '__main__':
    main()
